; 指定MBR 起始位置为 0x7c00
; 0x7c00 取值为约定，来源是：doc 1.0 内存最低要求 32K(0x8000), MBR 只有 512 字节，
; 但它运行需要栈，所以给 1K。为了尽量不被覆盖，需要将其放到 32K 的尾部（高1K的地方），
; 32K-1K=0x7c00
SECTION MBR vstart=0x7c00
    mov ax,cs   ; MBR进来时，cs 为0。所以这里与 mov ax,0 同意
    mov ds,ax   ; sreg 寄存器不能用立即数初始化（没有相应的电路），所以需要用寄存器进行
    mov es,ax
    mov ss,ax
    mov fs,ax
    mov sp,0x7c00   ; 当前0~0x7c00 暂时是安全的，所以以它为栈，将 sp 置为0x7c00，运行过程中栈会向下生长

    ; 清屏
    mov ax,0x600    ; 清屏时，AH=0x06，功能号。由BIOS中断0x10定义
                    ; AL=0，上卷行数，0表示全部
    mov bx,0x700    ; BH 上卷行的属性
    
    mov cx,0        ; (CL,CH) 窗口左上角的 (X,Y) 位置，此处为(0,0)
    mov dx,0x184f   ; (DL,DH)窗口右下角(X,Y)位置，此处为(80,25)，即文本模式(80,25)；显卡上电后会被初始化为这种模式
    int 0x10    ; BIOS 中与屏幕相关的中断号

    ; 获取当前光标位置(显存中的位置)
    mov ah,3    ; 功能号3表示获取光标位置
    mov bh,0    ; 页号，从0开始。80*25的文本模式下，一页能显示80*25=2000个字符，
                ; 同时，一个字符需要2个字节，高字节是字符属性，低字节是 ASCII 码

    int 0x10    ; 执行中断，输出：ch=光标开始行、cl=光标结束行、dh=光标所在行号、dl=光标所在列号

    ; 打印字符串
    mov ax,message  ; 待打印的字符串位置
    mov bp,ax   ; bp 是基址寄存器，同时也可以用作通用寄存器(与ax一样，不同点在于它不能被分成两个8位寄存器使用)
                ; es:bp为串首地址(es也被初始化为0了)
    mov cx,5    ; cx为串长度，不包括结束串\0
    mov ax,0x1301   ; 功能号AH=0x13 显示字符及属性；al=0x01 为设置写字符方式，此处01表示显示并让光标跟随移动
    mov bx,0x2  ; bh=0，目标页号为0；bl=0x2，表示字符属性，此时是黑底绿字
    int 0x10    ; 调用打印，其中dx中存了当前输出的光标位置，由上一步获得

    jmp $       ; while true

    message db "1 MBR"  ; 需要打印的字符
    times 510-($-$$) db 0   ; 填充字节，使尾部对齐。$ 表示当前位置，$$ 表示当前段偏移
    db 0x55,0xaa    ; 结束字符，约定是0x55和0xaa
    ; db 0xaa,0x55